#!/usr/bin/env python3
import subprocess
import platform
import os


class Install:

    def __init__(self) -> None:
        self._machine = platform.machine()
        self._home_path = os.path.expanduser("~")
        self._current_path = os.path.abspath(os.path.dirname(__file__))
        self._dowload_path = os.path.join(self._current_path, "third_party")
        self._install_prefix = os.path.join(self._current_path, "install")

        if not os.path.exists(self._install_prefix):
            os.makedirs(self._install_prefix)

    def start(self):
        self._clone_setup()
        self._clone_nlohmann_json()
        self._clone_tinyxml2()
        self._clone_gfamily()
        self._clone_dds()

    def _clone_github_repo(self, repo_url, repo_name, *args):
        dowload_path = os.path.join(self._dowload_path, repo_name)
        if os.path.exists(dowload_path):
            print("repo exists: {}".format(dowload_path))
            return None
        command = "git clone {} {}".format(
            repo_url,
            dowload_path
        )
        for arg in args:
            command += " " + arg
        print("clone: {}".format(command))
        subprocess.run(command, shell=True)

    def _cmd(self, command):
        print("[command] {}".format(command))
        subprocess.run(command, shell=True)

    def _clone_setup(self):
        self._clone_github_repo(
            "https://github.com/minhanghuang/setup.git",
            "setup",
            "--depth=1"
        )
        os.chdir(os.path.join(self._dowload_path, "setup"))
        self._cmd("mkdir -p build")
        os.chdir("build")
        self._cmd(
            "cmake -DCMAKE_INSTALL_PREFIX={} ..".format(self._install_prefix))
        self._cmd("make install -j$(nproc)")
        os.chdir(self._current_path)

    # nlohmann/json是一个使用现代c++编写的一个json库，该库是head-only的
    def _clone_nlohmann_json(self):
        self._clone_github_repo(
            "https://github.com/nlohmann/json.git",
            "nlohmann_json",
            "--depth=1"
        )
        os.chdir(os.path.join(self._dowload_path, "nlohmann_json"))
        self._cmd("mkdir -p build")
        os.chdir("build")
        self._cmd(
            "cmake -DCMAKE_INSTALL_PREFIX={} -DBUILD_SHARED_LIBS=ON ..".format(self._install_prefix))
        self._cmd("make install -j$(nproc)")
        os.chdir(self._current_path)

    def _clone_tinyxml2(self):
        self._clone_github_repo(
            "https://github.com/leethomason/tinyxml2.git",
            "tinyxml2",
            "--single-branch",
            "--branch=8.0.0",
            "--depth=1"
        )
        os.chdir(os.path.join(self._dowload_path, "tinyxml2"))
        self._cmd("mkdir -p build")
        os.chdir("build")
        self._cmd(
            "cmake -DCMAKE_INSTALL_PREFIX={} -DBUILD_SHARED_LIBS=ON ..".format(self._install_prefix))
        self._cmd("make install -j$(nproc)")
        os.chdir(self._current_path)

    def _clone_gfamily(self):
        # google开源的gflags是一套命令行参数解析工具，比getopt功能更强大，使用起来更加方便，gflags还支持从环境变量、配置文件读取参数（可用gflags代替配置文件）
        self._clone_github_repo(
            "https://github.com/gflags/gflags.git",
            "gflags",
            "--single-branch",
            "--branch=v2.2.0",
            "--depth=1"
        )
        # google 出的一个C++轻量级日志库，支持以下功能：
        # ◆ 参数设置，以命令行参数的方式设置标志参数来控制日志记录行为；
        # ◆ 严重性分级，根据日志严重性分级记录日志；
        # ◆ 可有条件地记录日志信息；
        # ◆ 条件中止程序。丰富的条件判定宏，可预设程序终止条件；
        # ◆ 异常信号处理。程序异常情况，可自定义异常处理过程；
        # ◆ 支持debug功能；
        # ◆ 自定义日志信息；
        # ◆ 线程安全日志记录方式；
        # ◆ 系统级日志记录；
        # ◆ google perror风格日志信息；
        # ◆ 精简日志字符串信息
        self._clone_github_repo(
            "https://github.com/google/glog.git",
            "glog",
            "--single-branch",
            "--branch=v0.4.0",
            "--depth=1"
        )
        # 是由谷歌的测试技术团队开发的测试框架，使用c++实现，具有跨平台等特性
        self._clone_github_repo(
            "https://github.com/google/googletest.git",
            "googletest",
            "--single-branch",
            "--branch=release-1.10.0",
            "--depth=1"
        )

        # Protocol Buffers的简称，它是Google公司开发的一种数据描述语言，是一种轻便高效的结构化数据存储格式，可以用于结构化数据串行化，或者说序列化 。
        # 它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。
        self._clone_github_repo(
            "https://github.com/protocolbuffers/protobuf.git",
            "protobuf",
            "--single-branch",
            "--branch=v3.14.0",
            "--depth=1"
        )

        os.chdir(os.path.join(self._dowload_path, "gflags"))
        self._cmd("mkdir -p build")
        os.chdir("build")
        self._cmd(
            "cmake -DCMAKE_CXX_FLAGS='-fPIC' -DCMAKE_INSTALL_PREFIX={} -DBUILD_SHARED_LIBS=ON ..".format(
                self._install_prefix))
        self._cmd("make install -j$(nproc)")
        os.chdir(self._current_path)

        os.chdir(os.path.join(self._dowload_path, "glog"))
        self._cmd("mkdir -p build")
        os.chdir("build")
        self._cmd(
            "cmake -DCMAKE_CXX_FLAGS='-fPIC' -DCMAKE_INSTALL_PREFIX={} -DBUILD_SHARED_LIBS=ON ..".format(
                self._install_prefix))
        self._cmd("make install -j$(nproc)")
        os.chdir(self._current_path)

        os.chdir(os.path.join(self._dowload_path, "googletest"))
        self._cmd("mkdir -p build")
        os.chdir("build")
        self._cmd(
            "cmake -DCMAKE_CXX_FLAGS='-fPIC -w' -DCMAKE_INSTALL_PREFIX={} -DBUILD_SHARED_LIBS=ON ..".format(
                self._install_prefix))
        self._cmd("make install -j$(nproc)")
        os.chdir(self._current_path)

        os.chdir(os.path.join(self._dowload_path, "protobuf"))
        os.chdir("cmake")
        self._cmd("mkdir -p build")
        os.chdir("build")
        self._cmd(
            "cmake -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX={} ..".format(
                self._install_prefix))
        self._cmd("make install -j$(nproc)")
        os.chdir(self._current_path)

    # 
    # Fast-RTPS是eprosima对于RTPS的C++实现，是一个免费开源软件，遵循Apache License 2.0
    # Fast-RTPS现在被称为Fast-DDS，作为ROS2的默认中间件
    # 具有以下优点：
    # 对于实时应用程序来说，可以在best-effort和reliable两种策略上进行配置
    # 即插即用的连接性，使网络的所有成员自动发现其他新成员
    # 模块化和可扩展性允许网络中设备不断增长
    # 可配置的网络行为和可互换的传输层：为每个部署选择最佳协议和系统输入/输出通道组合
    # 两个API层：一个简单易用的发布者--订阅者层；一个提供对RTPS协议内部更好控制的Writer--Reader层 
    def _clone_dds(self):
        # self._clone_github_repo(
        #     "https://github.com/eProsima/Fast-RTPS.git",
        #     "Fast-RTPS",
        #     "--single-branch",
        #     "--branch=v1.5.0",
        #     "--depth=1"
        # )
        # os.chdir(os.path.join(self._dowload_path, "Fast-RTPS"))
        # self._cmd("git submodule update --init")
        # self._cmd("patch -p1 < {}".format(os.path.join(self._current_path,
        #           "scripts/FastRTPS_1.5.0.patch")))
        # self._cmd("mkdir -p build")
        # self._cmd(
        #     "cmake -DEPROSIMA_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX={} ..".format(
        #         self._install_prefix))
        # os.chdir(self._current_path)

        dds_name = "fast-rtps-1.5.0-1.prebuilt.x86_64.tar.gz"
        if "x86_64" == self._machine:
            pass
        else:
            dds_name = "fast-rtps-1.5.0-1.prebuilt.aarch64.tar.gz"

        if os.path.exists(os.path.join(self._dowload_path, dds_name)):
            return None

        self._cmd(
            "wget -t 10 {} -P {}".format(
                "https://apollo-system.cdn.bcebos.com/archive/6.0/{}".format(dds_name),
                self._dowload_path),
        )
        os.chdir(self._dowload_path)
        self._cmd("tar -zxvf {}".format(dds_name))
        self._cmd("cp -r fast-rtps-1.5.0-1/* {}".format(self._install_prefix))
        self._cmd("rm -rf fast-rtps-1.5.0-1/")
        os.chdir(self._current_path)


if __name__ == "__main__":
    install = Install()
    install.start()
